package megamek.common.actions;

import static org.junit.Assert.assertEquals;

import java.util.Vector;

import megamek.client.bot.TestBot;
import megamek.common.Board;
import megamek.common.Coords;
import megamek.common.Entity;
import megamek.common.EquipmentType;
import megamek.common.GunEmplacement;
import megamek.common.Hex;
import megamek.common.MiscType;
import megamek.common.Mounted;
import megamek.common.Player;
import megamek.common.Tank;
import megamek.common.TargetRoll;
import megamek.common.Targetable;
import megamek.common.ToHitData;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

// TODO: Auto-generated Javadoc
/**
 * The Class ClubAttackActionTest.
 */
public class ClubAttackActionTest
{

	/** The bot. */
	static TestBot bot;

	/** The attacker. */
	static Player attacker = new Player(1, "attacker");

	/** The target. */
	static Player target = new Player(1, "target");

	/** The attack action. */
	static ClubAttackAction attackAction;

	/** The club. */
	static Mounted club;

	/** The equipment type. */
	static MiscType miscType;

	/** The target ent. */
	static Entity attackerEnt, targetEnt;
	
	/** The entities. */
	static Vector<Entity> entities;

	/**
	 * Sets the up before class.
	 * 
	 * @throws Exception
	 *             the exception
	 */
	@BeforeClass
	public static void setUpBeforeClass() throws Exception
	{
		// add the players to the game
		bot = new TestBot("game", "localhost", 111);
		bot.game.addPlayer(attacker.getId(), attacker);
		bot.game.addPlayer(target.getId(), target);

		// create the board and hexs to fill the board
		bot.game.setBoard(new Board(3, 3));
		for (int i = 0; i < bot.game.getBoard().getWidth(); i++)
		{
			for (int j = 0; j < bot.game.getBoard().getHeight(); j++)
			{
				bot.game.getBoard().setHex(new Coords(i, j), new Hex(0));
			}
		}

		// add the entities to the game
		attackerEnt = new GunEmplacement();
		attackerEnt.setOwner(attacker);
		attackerEnt.setId(15);
		attackerEnt.setPosition(new Coords(0, 0));
		attackerEnt.setWeight(200);

		targetEnt = new Tank();
		targetEnt.setOwner(target);
		targetEnt.setId(20);
		targetEnt.setPosition(new Coords(1, 1));

		entities = new Vector<Entity>();
		entities.add(attackerEnt);
		entities.add(targetEnt);
		bot.game.setEntitiesVector(entities);

		club = new Mounted(attackerEnt, new MiscType());

		attackAction = new ClubAttackAction(attackerEnt.getId(), target.getId(), club, 0);
	}

	/**
	 * Tear down after class.
	 * 
	 * @throws Exception
	 *             the exception
	 */
	@AfterClass
	public static void tearDownAfterClass() throws Exception
	{
	}

	/**
	 * Sets the up.
	 * 
	 * @throws Exception
	 *             the exception
	 */
	@Before
	public void setUp() throws Exception
	{
	}

	/**
	 * Tear down.
	 * 
	 * @throws Exception
	 *             the exception
	 */
	@After
	public void tearDown() throws Exception
	{
	}

	/**
	 * Test get damage for.
	 */
	@Test
	public void testGetDamageFor()
	{
		// there is only the entity its self so only the weight is what
		// determines the damage inflicted.
		int damage = ClubAttackAction.getDamageFor(attackerEnt, club, false);
		assertEquals((attackerEnt.getWeight() / 5), damage, 0.001);

		club.getType().setSubType((int) MiscType.S_SWORD);
		damage = ClubAttackAction.getDamageFor(attackerEnt, club, false);
		assertEquals(((attackerEnt.getWeight() / 10) + 1), damage, 0.001);
	}

	/**
	 * Test to hit i game.
	 */
	@Test
	public void testToHitIGame()
	{
		ToHitData expected = new ToHitData(TargetRoll.IMPOSSIBLE, "A friendly unit can never be the target of a direct attack.");
		attackAction.setTargetType(Targetable.TYPE_ENTITY);
		attackAction.setTargetId(targetEnt.getId());
		ToHitData actual = attackAction.toHit(bot.game);
		assertEquals(expected, actual);
	}

	/**
	 * Test get club.
	 */
	@Test
	public void testGetClub()
	{
		assertEquals(club, attackAction.getClub());
	}

	/**
	 * Test set club.
	 */
	@Test
	public void testSetClub()
	{
		Mounted newClub = new Mounted(targetEnt, new EquipmentType());
		attackAction.setClub(newClub);
		assertEquals(newClub, attackAction.getClub());
	}

}
